// Copyright 2011-2012, Vanya Davidenko.
// Используемая кодировка: UTF-8.

#ifndef LIBV_BOOST_XML_INTERNAL_XML_ATRIBUTES_ITERATOR_HPP_
#define LIBV_BOOST_XML_INTERNAL_XML_ATRIBUTES_ITERATOR_HPP_

#include <boost/iterator/iterator_facade.hpp>
#include <libv/check.h>
#include <libv/boost/xml/xml_node.h>



namespace libv {

// (!) Итератор возвращает временные объекты,
//     которые нужно копировать, а не сохранять по ссылке.
class XmlNode::AttributesIterator
    : public boost::iterator_facade<XmlNode::AttributesIterator,
                                    const XmlAttribute,
                                    ::std::bidirectional_iterator_tag,
                                    const XmlAttribute> {
  friend class XmlNode;
  friend class boost::iterator_core_access;
  public:
    // Итератор, создаваемый методом end().
    AttributesIterator() {}

    // Проверка достижения итератором начала.
    bool AtBegin() const {
        return current_.pimpl_->previous_attribute() == NULL;
    }

    // Проверка достижения итератором конца.
    bool AtEnd() const {
        return current_.IsNull();
    }

  private:
    AttributesIterator(const XmlNode& node)
      : current_(node.pimpl_->first_attribute(), new XmlNode(node)) {}

    void increment() {
        LIBV_PRECOND(!AtEnd());
        current_.pimpl_ = current_.pimpl_->next_attribute();
    }

    void decrement() {
        LIBV_PRECOND(!AtBegin());
        current_.pimpl_ = current_.pimpl_->previous_attribute();
    }

    const XmlAttribute& dereference() const {
        LIBV_PRECOND(!AtEnd());
        return current_;
    }

    bool equal(const AttributesIterator& rhv) const {
        return current_ == rhv.current_;
    }

    XmlAttribute current_;
};

}  // libv

#endif  // LIBV_BOOST_XML_INTERNAL_XML_ATRIBUTES_ITERATOR_HPP_
